/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.logging.appender;

import org.zhiqim.kernel.util.Files;

/**
 * 文件大小滚动增加器，根据大小切换日志文件，格式如info.log,info.log.1,...
 *
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 */
public class FileSizeAppender extends FileAppender
{
    private final Object lock = new Object();     //文件锁
    
    @Override
    public void setFilePath(String filePath)
    {
        super.setFilePath(filePath);
        doCreateWriter();
    }
    
    @Override
    public void append(int level, String message, Throwable throwable)
    {
        if (super.getFileSize() >= fileMaxSize)
            doConvertWriter();
            
        print(level, message, throwable);
    }
    
    /** 创建文件输出器 */
    private void doCreateWriter()
    {//由外部第一次设置时
        synchronized (lock)
        {
            if (super.getWriter() != null)
                return;//当前输出器已创建成功，表示已创建，直接返回（并发双重检查）
            
            if (super.getFileSize() >= fileMaxSize)
            {//如果当前的大于最大值，则删除可能大于该索引的值，重命名 .1,.2,.3成.2,.3,.4
                Files.removeMaxFileAndRenameFile(fileDir, fileName, fileMaxNum, true);
            }
            
            //创建新的当前输出器
            super.createWriter();
        }
    }
    
    /** 变更文件输出器 */
    private void doConvertWriter()
    {
        synchronized (lock)
        {
            if (super.getFileSize() < fileMaxSize)
            {//当前文件小于最大值，表示已创建，直接返回（并发双重检查）
                return;
            }
            
            //关闭上一个输出器
            super.closeWriter();    
            
            //删除可能大于该索引的值，重命名 .1,.2,.3成.2,.3,.4
            Files.removeMaxFileAndRenameFile(fileDir, fileName, fileMaxNum, true);
            
            //创建新的当前输出器
            super.createWriter();
        }
    }
}
